<?php
/**
 * Created by PhpStorm.
 * User: BlueIdeaLirui
 * Date: 2019/09/04
 * Time: 14:58
 */

namespace business\elasticsearch\services;

use business\elasticsearch\repositories\LandDetailsRepository;
use business\elasticsearch\types\LandDetailsAggsType;
use business\elasticsearch\types\LandUsageType;

class LandDetailsService
{
    /**
     * 市场数据-土地详情数据列表
     * @param $developerUid
     * @param $companyName
     * @param $region
     * @param $takeLandStartDate
     * @param $takeLandEndDate
     * @param $landUsage
     * @param $page
     * @param $pageSize
     * @return array
     */
    public function getLandTakeList
    (
        $developerUid,
        $companyName,
        $region,
        $takeLandStartDate,
        $takeLandEndDate,
        $landUsage,
        $page,
        $pageSize
    ) {
        $page = max($page, 1);

        $query = [];

        // 构建查询条件
        static::builerLandTakeQueryConds(
            $query, $developerUid, $companyName, $region, $takeLandStartDate, $takeLandEndDate, $landUsage);

        $from = ($page - 1) * $pageSize;

        $include = [
            'uid'
            , 'developer_uid'
            , 'company_name'
            , 'project_name'
            , 'land_usage'
            , 'take_land_price'
            , 'area'
            , 'take_land_date'
            , 'address'
            , 'province'
            , 'city'
            , 'used_condition'
            , 'remark'
            , 'effective_period'
        ];

        list($total, $data) = (new LandDetailsRepository())->queryLandTakeList($query, $include,
            static::constructingAggs(), $from, $pageSize);

        $list = static::filterParameter($data['hits']['hits']);

        if (!empty($list)) {
            foreach ($list as & $item) {
                $item['area']             = (float)$item['area'];
                $item['effective_period'] = (int)$item['effective_period'];
                $item['take_land_price']  = (float)$item['take_land_price'];
                $item['developer_uid']    = (int)$item['developer_uid'];
                $item['uid']              = (int)$item['uid'];
            }
        }

        return [
            'total' => $total
            , 'list' => !empty($list) ? $list : null
            , 'totalfee' => round($data['aggregations']['totalfee']['value'], 2)
            , 'totalarea' => round($data['aggregations']['totalarea']['value'], 2)
        ];
    }

    /**
     * 市场数据-开工数据详情列表
     * @param $developerUid
     * @param $companyName
     * @param $page
     * @param $pageSize
     */
    public function getLandConstructionList
    (
        $developerUid,
        $companyName,
        $region = '',
        $contractStartTime = '',
        $contractEndTime = '',
        $page,
        $pageSize
    ) {
        $page = max($page, 1);

        $query = [];

        // 构建查询条件
        static::builderLandConstructionQueryConds(
            $query, $developerUid, $companyName, $region, $contractStartTime, $contractEndTime);

        $from = ($page - 1) * $pageSize;

        $include = [
            'uid'
            , 'developer_uid'
            , 'company_name'
            , 'project_name'
            , 'province'
            , 'city'
            , 'licences'
            , 'issuing_time'
            , 'construction_unit'
            , 'contract_start_time'
            , 'contract_end_time'
            , 'area'
            , 'contract_price'
        ];

        list($total, $data) = (new LandDetailsRepository())->queryLandConstructionList($query, $include,
            static::constructingAggs('land_construction'), $from, $pageSize);

        $list = static::filterParameter($data['hits']['hits']);

        if (!empty($list)) {
            foreach ($list as & $item) {
                $item['area']                = (float)$item['area'];
                $item['contract_end_time']   = $item['effective_period'] ?? '';
                $item['contract_start_time'] = $item['contract_start_time'] ?? '';
                $item['contract_price']      = (float)$item['contract_price'];
                $item['developer_uid']       = (int)$item['developer_uid'];
                $item['uid']                 = (int)$item['uid'];
            }
        }

        return [
            'total' => $total
            , 'list' => !empty($list) ? $list : null
            , 'totalfee' => round($data['aggregations']['totalfee']['value'], 2)
            , 'totalarea' => round($data['aggregations']['totalarea']['value'], 2)
        ];
    }

    /**
     * 市场数据-项目数据详情列表
     * @param $developerUid
     * @param $companyName
     * @param string $region
     * @param string $openingStartTime
     * @param string $openingEndTime
     * @param string $decorate
     * @param $page
     * @param $pageSize
     * @return array
     */
    public function getLandProjectList
    (
        $developerUid,
        $companyName,
        $region = '',
        $openingStartTime = '',
        $openingEndTime = '',
        $decorate = '',
        $page,
        $pageSize
    ) {
        $page = max($page, 1);

        $query = [];

        // 构建查询条件
        static::builderLandProjectQueryConds(
            $query, $developerUid, $companyName, $region, $openingStartTime, $openingEndTime, $decorate);

        $from = ($page - 1) * $pageSize;

        $include = [
            'uid'
            , 'developer_uid'
            , 'company_name'
            , 'project_name'
            , 'province'
            , 'city'
            , 'area'
            , 'price'
            , 'property_category'
            , 'covered_area'
            , 'volume_rate'
            , 'greening_rate'
            , 'households'
            , 'address'
            , 'opening_time'
            , 'delivery_time'
            , 'property_years'
            , 'architectural_style'
            , 'decorate'
        ];

        list($total, $data) = (new LandDetailsRepository())->queryLandProjectList($query, $include,
            static::constructingAggs('land_project'), $from, $pageSize);

        $list = static::filterParameter($data['hits']['hits']);

        if (!empty($list)) {
            foreach ($list as & $item) {
                $item['area']          = (float)$item['area'];
                $item['opening_time']  = $item['opening_time'] ?? '';
                $item['developer_uid'] = (int)$item['developer_uid'];
                $item['uid']           = (int)$item['uid'];
                $item['volume_rate']   = (float)$item['volume_rate'];
                $item['price']         = (float)$item['price'];
            }
        }

        return [
            'total' => $total
            , 'list' => !empty($list) ? $list : null
            , 'totalarea' => round($data['aggregations']['totalarea']['value'], 2)
        ];
    }

    /**
     * 过滤数据
     * @param array $data
     * @param string $key
     * @return array
     */
    protected static function filterParameter
    (
        $data = [],
        $key = '_source'
    ) {
        $arrs = [];
        if (!empty($data)) {
            foreach ($data as $item) {
                $arrs[] = $item[$key];
            }
        }

        return $arrs;
    }

    /**
     * 构建项目地区查询
     * @param array $bool
     * @param $region
     */
    protected static function builerAreaQuery
    (
        &$bool = [],
        $region
    ) {
        if (!empty($region)) {
            $region = explode(',', $region);
            foreach ($region as $item) {
                $keys = [
                    'city'
                    , 'city_code.keyword'
                    , 'province'
                    , 'province_code.keyword'
                ];
                if (!empty($keys)) {
                    array_walk($keys,
                        function
                        (
                            $value
                        )
                        use (
                            &$bool,
                            $item
                        ) {
                            $bool[0]['bool']['should'][] = [
                                'match_phrase' => [
                                    $value => $item
                                ]
                            ];
                        });
                }
            }
        }
    }

    /**
     * 构建土地数据查询条件
     * @param array $query
     * @param $developerUid
     * @param $companyName
     * @param $region
     * @param $startDate
     * @param $endDate
     * @param $landUsage
     */
    protected static function builerLandTakeQueryConds(
        &$query = [],
        $developerUid,
        $companyName,
        $region,
        $startDate,
        $endDate,
        $landUsage
    ) {
        // 构建时间周期查询
        if (!empty($startDate)
            && !empty($endDate)) {
            $query['bool']['must'][] = [
                'range' => [
                    'take_land_date' => [
                        'gte' => date('Y-m-01', strtotime($startDate)),
                        'lte' => date('Y-m-t', strtotime($endDate))
                    ]
                ]
            ];
        }

        $bool = [];

        // 构建项目地区查询
        static::builerAreaQuery($bool, $region);

        !empty($developerUid)
            && $bool[1]['bool']['should'][] = [
            'match_phrase' => [
                'developer_uid' => $developerUid
            ]
        ];

        // 构建项目用途查询
        if (!empty($landUsage)) {
            $landUsage = explode(',', $landUsage);
            $usages    = [];
            foreach ($landUsage as $usage) {
                $subclass = LandUsageType::$usage[$usage];
                if (!empty($subclass)) {
                    foreach ($subclass as $name) {
                        $usages[] = $name;
                    }
                } else {
                    $usages[] = $usage;
                }
            }

            if (!empty($usages)) {
                foreach ($usages as $value) {
                    $bool[2]['bool']['should'][] = [
                        'match_phrase' => [
                            'land_usage.keyword' => $value
                        ]
                    ];
                }
            }
        }

        $query['bool']['must'][] = $bool;
    }

    /**
     * 构建项目数据查询条件
     * @param array $query
     * @param $developerUid
     * @param $companyName
     * @param string $region
     * @param string $openingStartTime
     * @param string $openingEndTime
     * @param string $decorate
     */
    protected static function builderLandProjectQueryConds
    (
        &$query = [],
        $developerUid,
        $companyName,
        $region = '',
        $openingStartTime = '',
        $openingEndTime = '',
        $decorate = ''
    ) {
        // 构建时间周期查询
        if (!empty($openingStartTime)
            && !empty($openingEndTime)) {
            $query['bool']['must'][] = [
                'range' => [
                    'opening_time' => [
                        'gte' => date('Y-m-01', strtotime($openingStartTime)),
                        'lte' => date('Y-m-t', strtotime($openingEndTime))
                    ]
                ]
            ];
        }

        $bool = [];

        // 构建项目地区查询
        static::builerAreaQuery($bool, $region);

//        !empty($developerUid)
//        && $bool[1]['bool']['should'][] = [
//            'match_phrase' => [
//                'developer_uid' => $developerUid
//            ]
//        ];

        !empty($companyName)
        && $bool[1]['bool']['should'][] = [
            'match_phrase' => [
                'company_name.keyword' => $companyName
            ]
        ];

        // 构建装修查询
        if (!empty($decorate) && $decorate != '全部') {
            $decorates = explode(',', $decorate);
            foreach ($decorates as $decorate) {
                $bool[2]['bool']['should'][] = [
                    'match_phrase' => [
                        'decorate.keyword' => $decorate
                    ]
                ];
            }
        }

        $query['bool']['must'][] = $bool;
    }

    /**
     * 构建开工数据查询条件
     * @param array $query
     * @param $developerUid
     * @param $companyName
     * @param string $region
     * @param string $contractStartTime
     * @param string $contractEndTime
     */
    protected static function builderLandConstructionQueryConds
    (
        &$query = [],
        $developerUid,
        $companyName,
        $region = '',
        $contractStartTime = '',
        $contractEndTime = ''
    ) {
        // 构建时间周期查询
        if (!empty($contractStartTime)
            && !empty($contractEndTime)) {
            $query['bool']['must'][] = [
                'range' => [
                    'issuing_time' => [
                        'gte' => date('Y-m-01', strtotime($contractStartTime)),
                        'lte' => date('Y-m-t', strtotime($contractEndTime))
                    ]
                ]
            ];
        }

        $bool = [];

        // 构建项目地区查询
        static::builerAreaQuery($bool, $region);

        !empty($developerUid)
        && $bool[1]['bool']['should'][] = [
            'match_phrase' => [
                'developer_uid' => $developerUid
            ]
        ];

        $query['bool']['must'][] = $bool;
    }

    /**
     * 构建聚合条件
     * @return array
     */
    protected static function constructingAggs($key = 'land_take')
    {
        $aggsArr = LandDetailsAggsType::$aggs;

        $rtn = [];

        array_walk($aggsArr[$key],
            function ($value)
            use (
                &$rtn
            ) {
            if (!empty($value)) {
                array_push($rtn, [
                    'name' => $value['name'],
                    'options' => [
                        'sum' => [
                            'field' => $value['field']
                        ]
                    ]
                ]);
            }
        });

        return $rtn;
    }
}
